
let { tools } = require("./utils/util");
let { getDayName } = require('./data/tools/getDayName');
let isUpdateTime = '';
let setTime = null;
let scorllInitTop = 0;

// 渲染任务栏时间
function renderTaskBarDate(pyload, date = tools.formatTime(new Date())) {
    let cur = new Date(date);
    let curr = tools.formatTime(cur);
    let dycalendar = document.querySelector('.taskbar .right .dycalendar');
    dycalendar = dycalendar ? dycalendar : tools.myCreateElement('dycalendar', 'div');
    if (curr.slice(0, -3) != isUpdateTime.slice(0, -3)) {
        isUpdateTime = curr;
        let nowTime = tools.myCreateElement('now-time', 'div');
        nowTime.innerText = curr.split(' ')[1].slice(0, -3);
        let nowDate = tools.myCreateElement('now-date', 'div');
        nowDate.innerText = curr.split(' ')[0];
        dycalendar.replaceChildren(nowTime, nowDate);
    };
    requestAnimationFrame(renderTaskBarDate);// 更新时间
    return dycalendar;
};

function getData(cur) {// 获取表格数据
    let curr = tools.formatTime(cur);
    let prev = tools.changeData([cur, '', true, (data) => new Date(data)]);
    prev.setDate(0); prev.setDate(1);
    prev = tools.formatTime(prev);
    let next = tools.changeData([cur, '', true, (data) => new Date(data)]);
    next.setDate(1); next.setMonth(next.getMonth() + 1);
    next = tools.formatTime(next);
    let { head, content2, currWeek, currMonth, currDay, year } = tools.dycalendar(curr, 'all');
    let { content2: c2_prev, currMonth: cm_prev } = tools.dycalendar(prev, 'all');
    let { content2: c2_next, currMonth: cm_next } = tools.dycalendar(next, 'all');
    // let content2_bak = tools.changeData([[c2_prev, content2, c2_next], '', true]);
    let arr = [c2_prev, c2_next];
    arr.map((ele, ind, arr) => (arr[ind] = ele.reduce((p, e1) => (p.concat(content2.some(e2 => e2[0] == e1[0]) ? [] : [e1])), [])));
    [c2_prev, c2_next] = arr;
    content2 = [c2_prev, content2, c2_next].flat();
    return { head, content2, currWeek, currMonth, currDay, year, c2_prev, c2_next, cm_prev, cm_next, prev, next };
};

// 渲染日历表格
function getDycalendar(date = tools.formatTime(new Date())) {// date => Date对象 || 任意时间格式String
    let cur = new Date(date);
    let targetArr = [...document.querySelectorAll(`.rightContext .dycalendar .tableBox .div[data-cur-date]`)];
    let curDate = document.querySelector('.rightContext .dycalendar .top .date');

    let { head, content2, currWeek, currMonth, currDay, year, c2_prev, c2_next, cm_prev, cm_next, prev, next } = getData(cur);// 获取当前时间表格数据
    let table = tools.myCreateElement('table', 'table');
    let thead = tools.myCreateElement('thead', 'thead');
    let tr = document.createElement("tr");
    tr.classList.add('div');
    // 渲染表头
    head.map((ele) => {
        let td = document.createElement("td");
        td.innerText = ele;
        tr.append(td);
    });
    thead.append(tr);

    // 渲染表体
    let tbody = getDycalendarTbody(tools.myCreateElement('tbody', 'tbody'), content2, currMonth);
    const getprevData = (prev) => {// 渲染上个月
        // let targetArr = new Array(...dqSAll(`.rightContext .dycalendar .tableBox .div[data-cur-date]`));
        // let cur = document.querySelector('.rightContext .dycalendar .top .date');
        // let curr = null;
        // let curIndex = targetArr.findIndex(ele => {
        //     let flag = (ele.dataset.curDate == cur.innerText);
        //     flag && (curr = ele);
        //     return flag;
        // });

        // let prev = new Date(nowStr.innerText.replace(/[\u4e00-\u9fa5]/g, '-').slice(0, -1));
        let { c2_prev, cm_prev, prev: newPrev } = getData(new Date(prev));
        getDycalendarTbody(tbody, c2_prev, currMonth, true);

        return newPrev;
    };
    const getnextData = (next) => {// 渲染下个月
        let { c2_next, cm_next, next: newNext } = getData(new Date(next));
        getDycalendarTbody(tbody, c2_next, currMonth);
        return newNext;
    };

    prev = getprevData(prev);

    tbody.addEventListener('scroll', function (event) {
        clearTimeout(setTime);
        let topNum = this.scrollHeight - 270;
        if (this.scrollTop > topNum - (270 / 2)) {
            next = getnextData(next);
        };
        if (this.scrollTop < 270 * 3 / 2) {
            prev = getprevData(prev);
        };

        let tempArr = [...document.querySelectorAll('.rightContext .tableBox .tbody td:not(.curr)')];
        tempArr.map(e => e.classList.add('curr'));

        targetArr = [...document.querySelectorAll(`.rightContext .dycalendar .tableBox .div[data-cur-date]`)];
        curDate = document.querySelector('.rightContext .dycalendar .top .date');
        setTime = setTimeout(() => {// 监听滚动事件停止
            [...document.querySelectorAll('.rightContext .tableBox .tbody td.curr')].map(e => e.classList.remove('curr'));// 排他
            let temp = { startInd: -1, endInd: -1 };
            [...document.querySelector('.rightContext .tableBox .tbody').children].map((ele, i) => {
                if (((ele.dataset.curDate == curDate.innerHTML) || (temp.startInd != -1)) && temp.endInd == -1) {
                    let condition = temp.startInd == -1;// 判断是否开始添加curr类名
                    /**
                     * 分三层渲染,
                     * 第一层为当前月1号前的上个月日期,如29,30,31等,这些日期可能和当前月1号在表格同一行,渲染时不添加curr类名,1号后开始要添加curr类名,condition为true,
                     * 第二层为一号那一行之后的日期,根据condition判断即可,
                     * 第三层为下个月1号那一行,同第一层判断,也分29,30,31等,只是判断结果相反,1号之前需要添加curr类名,1号之后不用.
                     */
                    [...ele.children].reduce((flag, el) => {
                        flag = flag ? true : el.firstElementChild.innerHTML == 1;
                        flag && (temp[condition ? 'startInd' : 'endInd'] = i);
                        // el.classList[condition ? (flag ? 'add' : 'remove') : (flag ? 'remove' : 'add')]('curr');
                        el.classList[flag ^ condition ? 'remove' : 'add']('curr');// 使用异或(^)简化代码 
                        return flag;
                    }, false);
                };
            });
            scorllInitTop = 0;
        }, 186);

        if ((targetArr.length != 0) && curDate && (scorllInitTop != 0)) {// targetArr:包含1号的表格数据集合; curDate:当前时间; scorllInitTop:用来判断滚动方向
            let direction = this.scrollTop - scorllInitTop < 0 ? -1 : 1;// =>up:-1, down:1
            let ind = targetArr.findIndex(e => e.dataset.curDate == curDate.innerHTML);// 找出当前时间的索引,用于后面渲染上个月或下个月
            let condition = (targetArr[ind].offsetTop + targetArr[ind + direction]?.offsetTop) / 2;// 用来判断滚动是否达到当前月和上(下)月之间
            if (((direction > 0) && (this.scrollTop >= condition)) || ((direction < 0) && (this.scrollTop <= condition))) {
                curDate.innerHTML = targetArr[ind + direction].dataset.curDate;
            };
        } else {
            targetArr = [...document.querySelectorAll(`.rightContext .dycalendar .tableBox .div[data-cur-date]`)];
            curDate = document.querySelector('.rightContext .dycalendar .top .date');
        };


        scorllInitTop = this.scrollTop;
    });
    table.append(thead);
    table.append(tbody);
    return { table, head, content2, currWeek, currMonth, currDay, year, getprevData, getnextData };
};

// 将数据挂载到日历表格
function getDycalendarTbody(tbody, content, currMonth, isBefore) {
    let today = tools.formatTime(new Date()).split(' ')[0].replace(/\//g, '-');
    isBefore && content.reverse();
    content.map((el) => {
        let tr = document.createElement("tr");
        el.map((date) => {
            let td = document.createElement("td");
            tr.classList.add('div');
            let dayName = getDayName(date);
            let day = Number(date.slice(-2));
            let isCurrMonth = Number(date.slice(5, 7)) == currMonth;
            let isToday = date == today;
            date.slice(-2) == '01' && (tr.dataset.curDate = `${date.split('-')[0]}年${parseInt(date.split('-')[1])}月`);
            isCurrMonth && td.classList.add('curr');
            isToday && td.classList.add('currDay');
            td.innerHTML = `<div style="font-weight: 700;font-size: 14px;">${day}</div><div style="font-weight: 300;">${dayName}</div>`;
            tr.append(td);
        });
        isBefore ? tbody.insertBefore(tr, tbody.firstChild) : tbody.append(tr);
    });
    return tbody;
};

exports.dycalendarDom = renderTaskBarDate;
exports.getDycalendar = getDycalendar;
exports.getDycalendarTbody = getDycalendarTbody;